import { selectType, numField, passAttribute, defaultSelectData } from "@/options/config.js"
import { handleVerifySelectData } from "@/options/verify.js";


// 返回 rules 规则数组
const getRules = (msg = '不符合要求', type = 'blur', isRequired = true) => {
    return [
        {
            required: isRequired,
            message: msg,
            trigger: type
        }
    ]
}

const getRulesLengthMax = (max, min = 0) => {
    const ret = [
        {
            max,
            message: `最大长度为${max}位`,
        },
        {
            min,
            message: `最小长度为${min}位`,
        }
    ];
    if (min === 0) ret.splice(1, 1);
    return ret;
}

function getHideType(flag) {
    let result = null;
    switch (flag) {
        case 'form':
            result = {
                display: false,
            }
            break
        case 'column':
            result = {
                hide: true,
                showColumn: false,
            }
            break
        case 'all':
            result = {
                hide: true,
                showColumn: false,
                display: false,
            }
            break
    }
    return result;
}

/*
    返回自定义字典
        dataArr 二维数组构建 dicData => [[label, prop],[label, prop]]
        value 默认值
*/

function getDicOption(dataArr, value, type = "select") {
    if (!Array.isArray(dataArr)) return {}

    const result = {
        type,
        props: {
            label: "dictValue",
            value: "dictKey"
        },
        value,
        dicData: []
    }
    for (const [dictValue, dictKey] of dataArr) {
        result.dicData.push({ dictValue, dictKey });
    }
    return result;
}

// 组合函数
function compose(f, g) {
    return function (x) {
        return f(g(x));
    }
}

// 清空 空数据
function removeEmptyAttr(obj) {
    const text = JSON.stringify(obj);
    const reg = /"\$(\w+)"(.*?)/gs;
    const result = JSON.parse(text);
    // 删除$前缀的属性
    for (const item of text.matchAll(reg)) {
        const key = item[0].replace(/"/g, "");
        delete result[key]
    }
    // 删除为空的属性
    for (const key of Object.keys(result)) {
        if (result[key] === '') {
            delete result[key];
        }
    }

    if (result.label && result.prop) {
        result.label = result.label.replace(/\s/g, '');
        result.prop = result.prop.replace(/\s/g, '');
    }

    return result;
}
// 格式化对象数据为文本
function formatData(obj, division = 2, flag = false, isArray = false) {
    // 格式化
    const text = JSON.stringify(obj, "*", division);
    // 去掉key的""
    const reg = /"(\w+)"(?=:)/gs;
    let code = text.replace(reg, "$1");
    // 去掉前面和后面的 { }
    if (flag) {
        let regMustache;
        if (isArray) {
            regMustache = /^\[(?<code>.*?)\]$/gs;
        } else {
            regMustache = /^{(?<code>.*?)}$/gs;
        }
        code = regMustache.exec(code).groups.code;

        if (isArray) {
            code = code.slice(1);
        } else {
            code = code.replaceAll(' ', '').slice(1);
        }
    }
    return code
}

// 转换属性为数值
function formatNum(obj, fieldList) {
    const result = JSON.parse(JSON.stringify(obj));
    fieldList = fieldList || numField;
    for (const item of fieldList) {
        if (obj[item]) {
            result[item] = parseInt(obj[item]);
        }
    }
    return result;
}

function CopyObj(obj) {
    return JSON.parse(JSON.stringify(obj));
}

// 构建数据
function buildData(obj) {
    let result = CopyObj(obj);

    result = fastData(result);

    for (const key of Object.keys(result)) {
        const val = result[key];

        if (key === "hideType") {
            result = { ...result, ...getHideType(val) };
        }

        result = removeUselessAttr(result);

        if (key === "rules") {
            const max = result.rulesMax;
            const min = result.rulesMin || 0;
            if (val === "number" && max) {
                result.rules = [
                    ...getRulesLengthMax(parseInt(max), parseInt(min))
                ]
            }
            if (val === "trigger") {
                let str = '请输入';
                if (selectType.includes(result.type)) {
                    str = '请选择';
                }
                result.rules = [
                    ...getRules(str + result.label)
                ]
            }
        }
        if (selectType.includes(val)) {
            let dicData = null;
            if (result.selectData) {
                const dataArr = handleVerifySelectData(result.selectData);
                for (const data of dataArr) {
                    for (let item of data) {
                        item = item.toString();
                    }
                }
                if (dataArr.length) {
                    dicData = getDicOption(dataArr, result.value || dataArr[0][1], val);
                }
            } else {
                dicData = getDicOption(defaultSelectData, "0", val);
            }

            result = {
                ...result,
                ...dicData
            }

        }
        if (val === 'datetime') {
            result.format = "yyyy-MM-dd hh:mm:ss";
            result.valueFormat = "yyyy-MM-dd hh:mm:ss";
        }
        if (val === 'date') {
            result.format = "yyyy-MM-dd";
            result.valueFormat = "yyyy-MM-dd";
        }
        if (val === "time") {
            result.format = "hh-mm-ss";
            result.valueFormat = "hh:mm:ss";
        }
        if (val === "textarea") {
            result.maxlength = 500;
            result.span = 24;
            result.maxRows = 5;
            result.showWordLimit = true;
        }
        // 删除内部使用的字段
        if (passAttribute.includes(key)) {
            delete result[key]
        }
    }
    if (result.isDic) {
        result = removeProp(result, 'props,dicData,value,type,isDic');
        result = {
            ...result,
            type: "select",
            dicData: [],
            props: {
                label: "dictValue",
                value: "dictKey",
            },
        }
    }
    return result;
}

// 删除指定对象的属性
function removeProp(obj, keyStr) {
    if (typeof keyStr === 'string') keyStr = keyStr.split(',');
    if (!Array.isArray(keyStr)) keyStr = [keyStr];

    const ret = JSON.parse(JSON.stringify(obj));

    for (let key of keyStr) {
        key = key.trim();
        delete ret[key];
    }
    return ret;
}

// 删除一些默认值字段
function removeUselessAttr(result) {
    const ret = JSON.parse(JSON.stringify(result));
    deleteDefaultProp(ret, ['disabled', 'readonly', 'row', 'search', 'isDic', 'formslot', 'multiple'], false);
    deleteDefaultProp(ret, 'type', 'input');
    deleteDefaultProp(ret, 'searchSpan', '6');
    deleteDefaultProp(ret, 'searchLabelTitle', ret.label);
    deleteDefaultProp(ret, 'searchSpan', '8');

    if (ret.hideType === 'form' || ret.span === '12') {
        delete ret.span;
    }
    if (ret.hideType == 'column') {
        delete ret.hide;
        delete ret.showColumn;
    }
    return ret;
}

// 删除默认prop
function deleteDefaultProp(obj, prop, val) {

    if (typeof obj !== 'object' || !prop.length) return;

    if (Array.isArray(prop) && prop) {
        if (!prop.length) return

        for (const item of prop) {
            if (obj[item] === val) {
                delete obj[item];
            }
        }
    } else {
        if (obj[prop] === val) {
            delete obj[prop]
        }
    }


}


// 解析特殊符号转换为指定属性
function fastData(obj) {
    const ret = CopyObj(obj);

    // 日期
    let isDatetime = false;
    let isDate = false;
    // 文本域
    let isTextarea = false;
    // 下拉是否
    let isSelect = false;
    // 系统字典
    let isDic = false;
    // 必填
    let isRequire = false;

    const isSymbolFun = symbol => {
        const idx = ret.label.indexOf(symbol);
        return idx !== -1 ? true : false;
    }

    const replaceSymbol = (symbol) => {
        ret.label = ret.label.replace(symbol, "");
        ret.prop = ret.prop.replace(symbol, "");
    }

    if (isSymbolFun("&&")) {
        isDatetime = true;
        replaceSymbol("&&");
    } else if (isSymbolFun("&")) {
        isDate = true;
        replaceSymbol("&");
    } else if (isSymbolFun("-")) {
        isTextarea = true;
        replaceSymbol("-");
    } else if (isSymbolFun("=")) {
        isSelect = true;
        replaceSymbol("=");
    }


    if (isDatetime) {
        ret.type = "datetime";
    } else if (isDate) {
        ret.type = "date";
    } else if (isTextarea) {
        ret.type = "textarea";
    } else if (isSelect) {
        ret.type = "select";
        ret.selectData = '["是","0"]||["否","1"]';
    }


    if (isSymbolFun("?")) {
        isDic = true;
        replaceSymbol("?");
    }

    if (isSymbolFun("*")) {
        isRequire = true;
        replaceSymbol("*");
    }

    // 后缀文本
    if (isSymbolFun(">")) {
        const strS = ret.label.split(">");
        ret.label = strS[0];
        ret.prop = '_' + strS[0];
        ret.append = strS[1];
    }

    if (isDic) {
        ret.type = "select";
        ret.isDic = true;
    }

    if (isRequire) {
        ret.isRules = true;
        ret.rules = "trigger";
    }
    return ret;
}


// 防抖函数
function debounce(fn, delay) {
    let t = null;
    return function () {
        clearTimeout(t);
        t = setTimeout(() => {
            fn.apply(this, arguments);
        }, delay);
    }
}


// 根据字符串读取值 a.b.c => data.a.b.c
function getValueByExp(data, exp) {
    // 没有 . 
    if (exp.indexOf('.') === -1) {
        return data[exp] ? data[exp] : data;
    }

    // 有 . 
    const keys = exp.split('.');

    let result = JSON.parse(JSON.stringify(data));
    keys.forEach(item => result = result[item]);
    return result;
}

function getLocalStorage(key) {
    const obj = window.localStorage.getItem(key);
    return JSON.parse(obj);
}
function setLocalStorage(key, val) {
    return window.localStorage.setItem(key, JSON.stringify(val));
}
function removeLocalStorage(key) {
    window.localStorage.removeItem(key);
}
function clearLocalStorage() {
    window.localStorage.clear();
}

export {
    getRules,
    getRulesLengthMax,
    getHideType,
    getDicOption,
    compose,
    removeEmptyAttr,
    formatData,
    formatNum,
    debounce,
    getValueByExp,
    CopyObj,
    buildData,
    getLocalStorage,
    setLocalStorage,
    removeLocalStorage,
    clearLocalStorage
}